function LiteTemplateEngine() {
    var self = this;
    this.cache = {};
    this.bTemplate = function (str, data) {
        var node = document.getElementById(str);
        //传入的是一个#id
        if (node) {
            if (self.cache[str]) {
                return self.cache[str];
            }
            //textarea或input则取value，其它情况取innerHTML
            var html = /^(textarea|input)$/i.test(node.nodeName) ? node.value : node.innerHTML;
            return self._compile(html);
        } else {
            //是模板字符串，则生成一个函数
            //如果直接传入字符串作为模板，则可能变化过多，因此不考虑缓存
            return self._compile(str);
        }
    };
    this._compile = function (tpl, data) {
        var re = /<%([^%>]+)?%>/g,
            //应该被立即执行的语句
            reExp = /(^( )?(if|for|else|switch|case|break|{|}))(.*)?/g,
            code = 'var r=[];\n',
            //利用游标来记录当前位置match[index]
            cursor = 0;
        var add = function (line, js) {
            //对于满足reExp的应该立即执行 不被添加到程序字符串中去:变量插入:普通字符串
            js ? code += line.match(reExp) ? line + '\n' : 'r.push(' + line + ');\n' :
                code += 'r.push("' + line.replace(/"/g, '\\"') + '");\n';
        };
        var match;
        while (match = re.exec(tpl)) {
            //普通字符串
            add(tpl.slice(cursor, match.index));
            //js
            add(match[1], true); // <-- say that this is actually valid js
            cursor = match.index + match[0].length;
        }
        add(tpl.substr(cursor, tpl.length - cursor));
        code += 'return r.join("");'; // <-- return the result
        var render = new Function(code.replace(/[\r\t\n]/g, ''));
        //有内容直接render返回编译好的字符串
        if (data) {
            return render.apply(data);
        }
        //没有内容就返回一个函数可以接受一个参数
        return function (data) {
            return render.call(data);
        };
    };
}